class EventEmitter {
  constructor() {
    this._events = Object.create(null);
  }
  on(event, fn) {
    if (Array.isArray(event)) {
      event.forEach(function (ev) {
        this.on(ev, fn);
      })
    } else {
      (this._events[event] || (this._events[event] = [])).push(fn);
    }
    return this;
  }

  off(event, fn) {
    if (arguments.length == 0) {
      this._events = Object.create(null);
      return this;
    }
    if (Array.isArray(event)) {
      event.forEach(function (ev) {
        this.off(ev, fn);
      })
      return this;
    }
    let fns = this._events[event];
    if (!fns) return this;
    for (let i = fns.length - 1; i >= 0; i--) {
      if (fns[i] === fn || fns[i].fn === fn) {
        this._events[event].splice(i, 1);
        break;
      }
    }
    return this;
  }

  once(event, fn) {
    var self = this;
    function on() {
      self.off(event, on);
      fn.apply(self, arguments);
    }
    on.fn = fn;
    self.on(event, on);
    return self;
  }

  emit(event) {
    var fns = this._events[event];
    if (fns) {
      var args = [];
      for (let i = 1; i < arguments.length; i++) {
        args.push(arguments[i]);
      }
      for (var i = 0;i < fns.length; i++) {
        try {
          fns[i].apply(this,args);
        } catch (e) {
          console.log(e);
        }
      }
    }
    return this;
  }
}


module.exports = EventEmitter;